package extend.db;

import extend.db.base.Command;
import extend.db.base.Query;
import extend.db.build.sql.Union;
import extend.db.util.DbUtil;
import java.lang.reflect.Array;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * sql 构建基类
 *<B>说明：</B>
 *<pre>
 * 实体类或 map 生成sql
 *</pre>
 *<B>示例：</B>
 *<pre>
 *  略
 *</pre>
 *<B>日志：</B>
 *<pre>
 *  略
 *</pre>
 *<B>注意事项：</B>
 *<pre>
 *  略
 *</pre>
 */
public class Builder
{

    /**
     * builder 表达式名称定义
     */

    // 等于
    public static final String EQ_EXP = "eq";
    // 不等于
    public static final String NEQ_EXP = "neq";
    // 大于
    public static final String GT_EXP = "gt";
    // 大于等于
    public static final String EGT_EXP = "egt";
    // 小于
    public static final String LT_EXP = "lt";
    // 小于等于
    public static final String ELT_EXP = "elt";
    // not like 操作
    public static final String NOTLIKE_EXP = "notlike";
    public static final String LIKE_EXP = "like";
    //  not in 操作
    public static final String NOTIN_EXP = "notin";
    // 原始表达式
    public static final String EXP_EXP = "exp";
    public static final String OR_EXP = "or";
    public static final String AND_EXP = "and";
    // 数值累加　field = field + 4
    public static final String INC_EXP = "inc";
    // 数值递减　field = field - 4
    public static final String DEC_EXP = "dec";
    public static final String RAW_EXP = "raw";
    public static final String AS_EXP = "as";
    public static final String IN_EXP = "in";
    public static final String XOR_EXP = "xor";

    public static final String ALL_UNION_MODEL = "all";




    protected static final String INSERT_INTO_SQL = "insert into ";
    protected static final String INSERT_VALUES_SQL = "values";
    protected static final String UPDATE_SQL_KEYWORD = "update ";
    protected static final String DELETE_SQL_KEYWORD = "delete from ";
    protected static final String SELECT_SQL_KEYWORD = "select ";
    protected static final String FROM_SELECT_SQL_KEYWORD = " from ";
    protected static final String INSERT_DATA_SET_SQL_KEYWORD = " SET ";
    protected static final String ALIAS_SQL_KEYWORD = " AS ";
    protected static final String SELECT_FIELD_DEFAULT_SQL_KEYWORD = "*";
    protected static final String ORDERBY_SQL_KEYWORD = " order by ";
    protected static final String GROUPBY_SQL_KEYWORD = " group by ";
    protected static final String HAVING_SQL_KEYWORD = "HAVING";
    protected static final String WHERE_SQL_KEYWORD = "WHERE";
    protected static final String LIMIT_SQL_KEYWORD = " limit ";
    protected static final String FOR_UPDATE_SQL_KEYWORD = " FOR UPDATE ";

    protected static final String UNION_ALL_SQL_KEYWORD = " UNION ALL ";
    protected static final String UNION_SQL_KEYWORD = " UNION ";



    /**
     * 数据库连接对象
     *<B>说明：</B>
     *<pre>
     *  略
     *</pre>
     */
    protected DbConnection dbConnection = null;

    /**
     * 表达式方法列表
     *<B>说明：</B>
     *<pre>
     *  略
     *</pre>
     */
    protected Map<String,String> builders = new HashMap<String,String>(){{
        put("exp","buildExpSql");
        put("field","buildFieldSql");
        put("in","bulidInWhereSql");
        put("notin","bulidInWhereSql");
        put("eq","bulidNormalWhere");
        put("neq","bulidNormalWhere");
        put("gt","bulidNormalWhere");
        put("egt","bulidNormalWhere");
        put("lt","bulidNormalWhere");
        put("elt","bulidNormalWhere");
        put("notlike","bulidNormalWhere");
        put("like","bulidNormalWhere");
    }};

    /**
     * sql 表达式
     *<B>说明：</B>
     *<pre>
     *  略
     *</pre>
     */
    protected final static Map<String,String> sqlComparison = new HashMap<String,String>(){{
        put("eq","=");
        put("neq","<>");
        put("gt",">");
        put("egt",">=");
        put("lt","<");
        put("elt","<=");
        put("notlike","NOT LIKE");
        put("like","LIKE");
        put("in","IN");
        put("notin","NOT IN");
    }};

    /**
     * 构造方法
     *<B>说明：</B>
     *<pre>
     *  略
     *</pre>
     * @param dbConnection
     */
    public Builder(DbConnection dbConnection)
    {
        this.dbConnection = dbConnection;
    }

    /**
     * 绑定参数
     *<B>说明：</B>
     *<pre>
     *  略
     *</pre>
     */
    protected Map<String,Object> bindParams = new LinkedHashMap<>();

    /**
     * 绑定参数名称计数器
     *<B>说明：</B>
     *<pre>
     *  略
     *</pre>
     */
    protected Map<String,Integer> bindNames = new LinkedHashMap<>();

    /**
     * 获取表达式对应的方法名
     *<B>说明：</B>
     *<pre>
     * 略
     *</pre>
     * @param comparison 表达式名称
     * @return string
     */
    protected String getSqlComparison(String comparison)
    {
        if (this.sqlComparison.containsKey(comparison)) {
            return this.sqlComparison.get(comparison);
        } else {
            return "";
        }
    }

    /**
     * 获取表达式对应的方法名
     *<B>说明：</B>
     *<pre>
     * 略
     *</pre>
     * @param expression 表达式名称
     * @return string
     */
    protected String getExpressionMethod(String expression)
    {
        if (this.builders.containsKey(expression)) {
            return this.builders.get(expression);
        } else {
            return "";
        }
    }

    /**
     * 获取表达式对应的方法名
     *<B>说明：</B>
     *<pre>
     * 略
     *</pre>
     * @param columnName 字段名
     * @param columnValue 字段值
     * @return string
     */
    protected String buildColumnValue(String columnName,Object columnValue)
    {
        String colValue = ':' + this.bindParam(columnName,columnValue);

        return colValue;
    }

    /**
     * 参数绑定
     *<B>说明：</B>
     *<pre>
     *  略
     *</pre>
     * @param columnName 绑定参数名
     * @param columnValue 绑定值
     * @return string 参数key
     */
    protected String bindParam(String columnName,Object columnValue)
    {
        String colName = "sys_" + columnName;
        int index;
        if (!this.bindNames.containsKey(colName)) {
            index = 2;
            this.bindNames.put(colName,2);
        } else {
            index = this.bindNames.get(colName);
            index++;
            this.bindNames.put(colName,index);
        }

        String key =  colName + "_" + index;
        this.bindParams.put(":" + key,columnValue);

        return key;
    }

    /**
     * 解析字段名
     *<B>说明：</B>
     *<pre>
     *  略
     *</pre>
     * @param columnName 字段名
     * @return String
     */
    protected String parseColumnName(String columnName)
    {
        StringBuilder sql = new StringBuilder();

        return sql.append("`") . append(columnName) .append( "`").toString();
    }

    /**
     * 解析名称
     *<B>说明：</B>
     *<pre>
     *  略
     *</pre>
     * @param columnValue 字段名
     * @return String
     */
    protected String parseColumnValue(Object columnValue)
    {
        StringBuilder sql = new StringBuilder();
        String valueJavaType = columnValue.getClass().getName();
        if (valueJavaType.equals(DbUtil.JAVA_TYPE_STRING)) {
            // 字符串
            sql.append("'").append((String)columnValue).append("'");
        } else {
            sql.append((String)columnValue);
        }

        return sql.toString();
    }


    /**
     * 创建Command对象
     *<B>说明：</B>
     *<pre>
     *  略
     *</pre>
     * @param query
     * @return Command
     */
    public Command buildParamsCommand (Query query)
    {

        try {
            Object[] call = query.getBuild();
            String methodName = (String)call[0];
            String sql = (String) DbUtil.invoke(methodName,this,query);
            Command command = this.createCommand(sql);

            this.bindParams.clear();
            this.bindNames.clear();

            return command;
        } catch (Exception e) {
            e.printStackTrace();
        }

        return  null;
    }

    /**
     * 创建Command对象
     *<B>说明：</B>
     *<pre>
     *  略
     *</pre>
     * @param sql
     * @return Command
     */
    public Command createCommand(String sql)
    {
        try {
            Map<String,Object> bindParams = new LinkedHashMap<>();
            // 浅复制一份map
            bindParams.putAll(this.bindParams);
            return  new Command(sql,bindParams);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }


    /**
     * 生成插入单行记录sql
     *<B>说明：</B>
     *<pre>
     *  略
     *</pre>
     * @param query
     * @return string
     */
    public String insert(Query query)
    {

        Map<String,Object> data = query.getData().get(0);

        String[] columns = new String[data.size()];
        String[] values = new String[data.size()];

        int i = 0;
        for (Map.Entry<String, Object> entry : data.entrySet()) {
            columns[i] = entry.getKey();
            Object value = entry.getValue();
            if (value instanceof List) {
                // 格式['name'=>['exp','+ name']]
                ArrayList expValue = (ArrayList) value;
                String operatorName = (String)expValue.get(0);
                Object operatorValue = expValue.get(1);
                values[i] = this.callBuildMethod(operatorName,entry.getKey(),operatorValue);
            } else {
                values[i] = this.buildColumnValue(columns[i],value);
            }

            i++;
        }

        StringBuilder sql = new StringBuilder();
        sql.append(INSERT_INTO_SQL)
                .append(this.parseTable(query.getTable()))
                .append(this.parseAlias(query.getAlias()))
                .append("(")
                .append(DbUtil.join(columns,","))
                .append(")")
                .append(INSERT_VALUES_SQL)
                .append("(")
                .append(DbUtil.join(values,","))
                .append(")")
                .append(this.parseLock(query.getLock()))
        ;

        return sql.toString();
    }

    /**
     * 批量插入
     *<B>说明：</B>
     *<pre>
     *  略
     *</pre>
     */
    public String insertAll(Query query)
    {
        List<Map<String,Object>> datas = query.getData();
        Set<String> columnsSet = datas.get(0).keySet();
        String[] columns = columnsSet.toArray(new String[columnsSet.size()]);
        String[] valuesSql = new String[datas.size()];
        int k = 0;

        for (Map<String,Object> data:datas) {
            String[] values = new String[data.size()];
            int i = 0;
            for (Map.Entry<String, Object> entry : data.entrySet()) {
                Object value = entry.getValue();
                if (value instanceof List) {
                    // 格式['name'=>['exp','+ name']]
                    ArrayList expValue = (ArrayList) value;
                    String operatorName = (String)expValue.get(0);
                    Object operatorValue = expValue.get(1);
                    values[i] = this.callBuildMethod(operatorName,entry.getKey(),operatorValue);
                } else {
                    values[i] = this.buildColumnValue(columns[i],value);
                }

                i++;
            }

            StringBuilder valueSql =  DbUtil.join(values,",");
            valuesSql[k] = valueSql.insert(0,"(").append(")").toString();
            k++;
        }

        StringBuilder sql = new StringBuilder();

        //boolean replace = query.getReplace() ? true : false;

        sql.append(INSERT_INTO_SQL)
                .append(this.parseTable(query.getTable()))
                .append(this.parseAlias(query.getAlias()))
                .append("(")
                .append(DbUtil.join(columns,","))
                .append(")")
                .append(INSERT_VALUES_SQL)
                .append(DbUtil.join(valuesSql,","))
                .append(this.parseLock(query.getLock()))
        ;

        return sql.toString();
    }



    /**
     * 生成 update sql
     *<B>说明：</B>
     *<pre>
     *  略
     *</pre>
     * @param query 命令对象
     * @return string
     */
    public String update(Query query)
    {

        try {
            StringBuilder sql = new StringBuilder(UPDATE_SQL_KEYWORD);
            sql.append(this.parseTable(query.getTable()))
                    .append(this.parseAlias(query.getAlias()))
                    .append(this.parseSet(query.getData().get(0)))
                    .append(this.parseWhere(query.getWhere()))
                    .append(this.parseOrderBy(query.getOrderBy()))
                    .append(this.parseLimit(query.getLimit()))
                    .append(this.parseLock(query.getLock()))
                    ;

            return sql.toString();
        } catch (Exception e) {
            e.printStackTrace();

            return "";
        }
    }

    /**
     * 生成 update sql
     *<B>说明：</B>
     *<pre>
     *  略
     *</pre>
     * @param query 命令对象
     * @return string
     */
    public String delete(Query query)
    {

        try {
            StringBuilder sql = new StringBuilder(DELETE_SQL_KEYWORD);
            sql.append(this.parseTable(query.getTable()))
                    .append(this.parseAlias(query.getAlias()))
                    .append(this.parseWhere(query.getWhere()))
                    .append(this.parseOrderBy(query.getOrderBy()))
                    .append(this.parseLimit(query.getLimit()))
                    .append(this.parseLock(query.getLock()))
            ;

            return sql.toString();
        } catch (Exception e) {
            e.printStackTrace();
            return "";
        }
    }

    /**
     * 生成 select sql
     *<B>说明：</B>
     *<pre>
     *  略
     *</pre>
     * @param query
     * @return string
     */
    public String select(Query query)
    {
        try {
            StringBuilder sql = new StringBuilder(SELECT_SQL_KEYWORD);
            sql.append(this.parseField(query.getField()))
                    .append(FROM_SELECT_SQL_KEYWORD)
                    .append(this.parseTable(query.getTable()))
                    .append(this.parseAlias(query.getAlias()))
                    .append(this.parseWhere(query.getWhere()))
                    .append(this.parseGroupBy(query.getGroupBy()))
                    .append(this.parseHaving(query.getHaving()))
                    .append(this.parseOrderBy(query.getOrderBy()))
                    .append(this.parseLimit(query.getLimit()))
                    .append(this.parseLock(query.getLock()))
                    .append(this.parseUnion(query.getUnion()))
            ;

            return sql.toString();
        } catch (Exception e) {
            e.printStackTrace();
            return "";
        }
    }


    /**
     * 解析 update set 数据
     *<B>说明：</B>
     *<pre>
     * 略
     *</pre>
     * @param data
     * @return String
     */
    protected String parseSet(Map<String,Object> data)
    {
        // 遍历 data
        String[] setSqls = new String[data.size()];
        // 计数器
        int i = 0;
        for (Map.Entry<String, Object> entry : data.entrySet()) {
            String columnValueSql = "";
            // 字段名
            String column = entry.getKey();
            // 字段值
            Object value = entry.getValue();
            // 验证值的类型value
            if (value instanceof List) {
                // 格式['name'=>['exp','+ name']]
                ArrayList expValue = (ArrayList) value;
                String operatorName = (String)expValue.get(0);
                Object operatorValue = expValue.get(1);
                columnValueSql = this.callBuildMethod(operatorName,entry.getKey(),operatorValue);
            } else {
                columnValueSql = this.buildValue(column,value,"=");
            }

            setSqls[i] = columnValueSql;
            i++;
        }

        StringBuilder sql = new StringBuilder();

        return sql.append(INSERT_DATA_SET_SQL_KEYWORD).append(DbUtil.join(setSqls,",")).toString();
    }

    /**
     * 解析表别名
     *<B>说明：</B>
     *<pre>
     * 略
     *</pre>
     * @param alias
     * @return String
     */
    public String parseAlias(String alias)
    {

        if (alias == null) {
            return "";
        }

        StringBuilder sql = new StringBuilder();
        if (alias.length() > 0) {
            return sql.append(ALIAS_SQL_KEYWORD).append(alias).toString();
        } else {
            return "";
        }
    }

    /**
     * 解析 select field 数据
     *<B>说明：</B>
     *<pre>
     * 略
     *</pre>
     * @param fields
     * @return String
     */
    protected String parseField(Object fields)
    {
        if (fields == null) {
            return SELECT_FIELD_DEFAULT_SQL_KEYWORD;
        }

        String fieldSql = "";

        if (fields instanceof String) {
            fieldSql = (String)fields;
        } else if (fields instanceof Map) {
            HashMap<String,Object> fieldsMap = (HashMap<String,Object>) fields;
            String[] fieldSqls = new String[fieldsMap.size()];
            int i = 0;
            for (Map.Entry<String, Object> entry : fieldsMap.entrySet()) {
                Object field = entry.getValue();
                if (field instanceof String) {
                    fieldSqls[i] = (String)field;
                } else if (field instanceof List) {
                    ArrayList expValue = (ArrayList) field;
                    String operatorName = (String)expValue.get(0);
                    Object operatorValue = expValue.get(1);
                    fieldSqls[i] = this.callBuildMethod(operatorName,entry.getKey(),operatorValue);
                }

                i++;
            }

            fieldSql = DbUtil.join(fieldSqls,",").toString();
        }

        return fieldSql;
    }

    /**
     * 解析 order 数据
     *<B>说明：</B>
     *<pre>
     * 略
     *</pre>
     * @param orderBy
     * @return String
     */
    protected String parseOrderBy(Map<String,Object> orderBy)
    {
        if (orderBy == null) {
            return "";
        }

        String[] orderSqls = new String[orderBy.size()];
        int i = 0;
        for (Map.Entry<String, Object> entry : orderBy.entrySet()) {
            Object sort = entry.getValue();
            if (sort instanceof List) {
                ArrayList expValue = (ArrayList) sort;
                String operatorName = (String)expValue.get(0);
                Object operatorValue = expValue.get(1);
                orderSqls[i] = this.callBuildMethod(operatorName,entry.getKey(),operatorValue);
            } else {
                String columnName = this.parseColumnName(entry.getKey());
                orderSqls[i] =  columnName + " " + sort;
            }

            i++;
        }

        StringBuilder sql = new StringBuilder(ORDERBY_SQL_KEYWORD);

        return sql.append(DbUtil.join(orderSqls,",")).toString();
    }

    /**
     * 解析 group 数据
     *<B>说明：</B>
     *<pre>
     * 略
     *</pre>
     * @param groupBy
     * @return String
     */
    protected String parseGroupBy(String[] groupBy)
    {
        if (groupBy == null) {
            return "";
        }

        String[] groupSqls = new String[groupBy.length];
        int i = 0;
        for (String groupColumnName:groupBy) {
            groupSqls[i] =  this.parseColumnName(groupColumnName);
            i++;
        }

        StringBuilder sql = new StringBuilder(GROUPBY_SQL_KEYWORD);
        return sql.append(DbUtil.join(groupSqls,",")).toString();
    }

    /**
     * 解析 having 数据
     *<B>说明：</B>
     *<pre>
     * 略
     *</pre>
     * @param where
     * @return String
     */
    protected String parseHaving(Map<String,Object> where)
    {
        return this.parseWhere(where,HAVING_SQL_KEYWORD);
    }

    /**
     * 解析 where 数据
     *<B>说明：</B>
     *<pre>
     * 略
     *</pre>
     * @param where
     * @return String
     */
    protected String parseWhere(Map<String,Object> where)
    {
        return this.parseWhere(where,WHERE_SQL_KEYWORD);
    }

    /**
     * 解析 where 数据
     *<B>说明：</B>
     *<pre>
     *  略
     *</pre>
     * @param where 字段名
     * @param sqlKeyword sql 关键词
     * @return string
     */
    protected String parseWhere(Map<String,Object> where,String sqlKeyword)
    {

        if (where == null) {
            return "";
        }

        String xor = AND_EXP;
        if (where.containsKey(XOR_EXP)) {
            xor = (String)where.get(XOR_EXP);
            where.remove(XOR_EXP);
        }

        String whereSql = (xor == AND_EXP) ? this.buildXorWhere(where,AND_EXP) : this.buildXorWhere(where,OR_EXP);
        if (sqlKeyword == null) {
            return whereSql;
        } else {
            StringBuilder sbWhereSql = new StringBuilder();
            sbWhereSql.append(" ")
                    .append(sqlKeyword)
                    .append(" ")
                    .append(whereSql);

            return sbWhereSql.toString();
        }
    }

    /**
     * 解析 limit sql
     *<B>说明：</B>
     *<pre>
     *  略
     *</pre>
     * @param limit 格式[size,offset]
     * @return string
     */
    public String parseLimit(int [] limit)
    {
        if (limit == null) {
            return "";
        }

        int size  = limit[0];
        int offset = limit[1];
        StringBuilder limitSql = new StringBuilder();
        if (offset > 0) {
            // 设置过起始位置
            limitSql.append(size).append(",").append(offset);
        } else {
            if (size > 0) {
                limitSql.append(size);
            }
        }

        if (limitSql.length() > 0) {
            return limitSql.insert(0,LIMIT_SQL_KEYWORD).toString();
        } else {
            return "";
        }
    }

    /**
     * 构建 lock sql
     *<B>说明：</B>
     *<pre>
     *  略
     *</pre>
     * @param lock 是否加锁
     * @return string
     */
    public String parseLock(boolean lock)
    {
        if (lock == false) {
            return "";
        }

        return FOR_UPDATE_SQL_KEYWORD;
    }

    /**
     * 解析联合查询
     *<B>说明：</B>
     *<pre>
     *  略
     *</pre>
     */
    protected String parseUnion(Union union)
    {
        if (union == null) {
            return "";
        }

        List<Query> querys = union.getQuerys();

        StringBuilder[] sqls = new StringBuilder[querys.size()];

        int i = 0;
        String unionMode = union.getUnionMode();
        String unionSqlKeyword;
        if (!unionMode.equals("") || unionMode.equals(ALL_UNION_MODEL)) {
            unionSqlKeyword = UNION_ALL_SQL_KEYWORD;
        } else {
            unionSqlKeyword = UNION_SQL_KEYWORD;
        }

        for (Query query:querys) {
            sqls[i] = new StringBuilder(unionSqlKeyword).append(this.select(query));
            i++;
        }

        return DbUtil.join(sqls,"").toString();
    }

    /**
     * 构建异或　where sql
     *<B>说明：</B>
     *<pre>
     *  略
     *</pre>
     * @param where 条件
     * @param xor 异或sql 关键词 and,or
     * @return string
     */
    public String buildXorWhere(Map<String,Object> where,String xor)
    {
        String[] whereSqls = new String[where.size()];

        // 定义计数器
        int i = 0;
        for (Map.Entry<String, Object> item : where.entrySet()) {
            whereSqls[i] = this.bluidWhereItem(item.getKey(),item.getValue());
            i++;
        }

        if (whereSqls.length == 0) {
            return "";
        }

        if (whereSqls.length == 1) {
            return  whereSqls[0];
        } else {
            return DbUtil.join(whereSqls," " + xor + " ").insert(0,"(").append(")").toString();
        }
    }

    /**
     * 构建where 条件项
     *<B>说明：</B>
     *<pre>
     *  略
     *</pre>
     * @param columnName 字段名
     * @param columnValue 字段值
     * @return String
     */
    protected String bluidWhereItem(String columnName,Object columnValue)
    {
        String sql;
        if (columnValue instanceof Map) {
            sql = this.parseWhere((HashMap<String,Object>)columnValue,null);
        } else {
            if (columnValue instanceof ArrayList) {
                ArrayList values = (ArrayList)columnValue;
                sql = this.callBuildMethod((String)values.get(0),columnName,values.get(1));
            } else {
                sql = this.callBuildMethod(EQ_EXP,columnName,columnValue);
            }
        }

        return  sql;
    }

    /**
     * 构建 where in 表达式
     *<B>说明：</B>
     *<pre>
     *  略
     *</pre>
     * @param operator 表达式
     * @param condition 表达式值
     * @return String
     */
    public String bulidInWhereSql(String operator,ArrayList condition)
    {
        String columnName = (String)condition.get(0);
        Object columnValue = condition.get(1);
        operator = this.getSqlComparison(operator);
        columnName = this.parseColumnName(columnName);
        StringBuilder sql = new StringBuilder();
        Class valueJavaType = columnValue.getClass();
        String inValueSql = "";

        if (valueJavaType.isArray()) {
            int valueLength = Array.getLength(columnValue);
            String[] inVals = new String[valueLength];
            for(int i = 0;i < valueLength;i++) {
                inVals[i] = this.buildColumnValue(columnName,Array.get(columnValue,i));
            }

            inValueSql = DbUtil.join(inVals,",").toString();
        } else {
            // 非数组
            inValueSql = (String)columnValue;
        }

        sql.append(columnName)
                .append(" ")
                .append(operator)
                .append(" (")
                .append(inValueSql)
                .append(")")
        ;

        return sql.toString();
    }

    /**
     * 构建 where eq 表达式
     *<B>说明：</B>
     *<pre>
     *  略
     *</pre>
     * @param operator 表达式
     * @param condition 表达式值
     * @return String
     */
    public String bulidNormalWhere(String operator,ArrayList condition)
    {

        String column = (String)condition.get(0);
        Object value = condition.get(1);
        value = this.buildColumnValue(column,value);
        column = this.parseColumnName(column);
        operator = this.getSqlComparison(operator);

        StringBuilder sql = new StringBuilder();
        sql.append(column)
                .append(" ")
                .append(operator)
                .append(" ")
                .append(value);

        return sql.toString();
    }


    /**
     * 构建key/value sql
     *<B>说明：</B>
     *<pre>
     *  比如 name = :sys_name_1
     *     或者name = 1
     *     或 name > 2
     *</pre>
     * @param columnName 字段名
     * @param columnValue 字段值
     * @param operator 操作符
     * @return string
     */
    protected String buildValue(String columnName ,Object columnValue,String operator)
    {
        StringBuilder sql = new StringBuilder();
        if (operator == null) {
            operator = "=";
        }

        columnName = this.parseColumnName(columnName);
        columnValue  = this.buildColumnValue(columnName,columnValue);

        sql.append(columnName)
                .append(" ")
                .append(operator)
                .append(" ")
                .append(columnValue);

        return sql.toString();
    }


    /**
     * 解析table
     *<B>说明：</B>
     *<pre>
     * 略
     *</pre>
     * @param table
     * @return string 表名，多个表名逗号隔开
     */
    protected String parseTable(String table)
    {
        String tb = this.getTableName(table,null);

        return tb;
    }

    /**
     * 构建 exp 表达式
     *<B>说明：</B>
     *<pre>
     *  略
     *</pre>
     * @param operator 表达式
     * @param condition 表达式值 [column,value]
     * @return String
     */
    public String buildExpSql(String operator,ArrayList condition)
    {
        String columnName = (String)condition.get(0);
        String columnValue = (String)condition.get(1);

        StringBuilder sql = new StringBuilder();
        sql.append(columnName)
                .append(" ")
                .append(columnValue);

        return sql.toString();
    }

    /**
     * 构建 field 表达式
     *<B>说明：</B>
     *<pre>
     *  常用与查插入记录场景
     *</pre>
     * @param operator 表达式
     * @param condition 表达式值 [column,value]
     * @return String
     */
    public String buildFieldSql(String operator,ArrayList condition)
    {
        String columnName = (String)condition.get(0);
        String columnValue = (String)condition.get(1);

        StringBuilder sql = new StringBuilder();
        if (columnValue instanceof String) {
            sql.append(this.buildColumnValue(columnName,columnValue));
        } else {

        }

        return sql.toString();
    }

    /**
     * 调用表达式方法
     *<B>说明：</B>
     *<pre>
     * 略
     *</pre>
     * @param  expression 表达式名称
     * @param  column 字段名
     * @param  value 字段值
     * @return string
     */
    public String callBuildMethod(String expression ,String column,Object value)
    {
        String method = this.getExpressionMethod(expression);
        try {
            ArrayList params = new ArrayList();
            params.add(column);
            params.add(value);
            Object[] args = {expression,params};

            return (String) DbUtil.invoke(method,this,args);
        } catch (Exception e) {
            e.printStackTrace();
            return "";
        }
    }

    /**
     * 获取真实表名
     *<B>说明：</B>
     *<pre>
     *  主要给表加前缀
     *</pre>
     * @param table  表名
     * @param prefix 表前缀
     * @return string
     */
    public String getTableName(String table,String prefix)
    {
        String regex = "\\{\\{%(.+?)\\}\\}";
        Pattern pattern = Pattern.compile(regex);
        Matcher matcher = pattern.matcher(table);

        if (matcher.find()) {
            if (prefix == null) {
                prefix = this.dbConnection.getPrefix();
            }

            table = prefix + matcher.replaceAll("$1");
        }

        return table;
    }

}
